/*
 * @Author: 肖思汗 
 * @Date: 2025-08-13 09:27:04 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2025-08-17 03:50:28
 */

import { ReactNode, useEffect, useRef, useState } from 'react';
import styles from './cropModel.module.less';
import { observer } from "mobx-react-lite";
import MyPopup from 'src/components/MyPopup/MyPopup';
import cropModelStore from './cropModelStore';
import closeSVG from "./img/close.svg";
import backSVG from "./img/back.svg";
import okSVG from "./img/ok.svg";
import utilsStore from 'src/utils/utilsStore';
import utils from 'src/utils/utils';
import Taro from '@tarojs/taro';
import { Canvas } from '@tarojs/components';
import cropEditor from './cropEditor';

import autoSVG from "./img/auto.svg";
import auto_hoverSVG from "./img/auto_hover.svg";
import SVG1_1 from "./img/1_1.svg";
import SVG1_1_hover from "./img/1_1_hover.svg";
import SVG2_3 from "./img/2_3.svg";
import SVG2_3_hover from "./img/2_3_hover.svg";
import SVG3_2 from "./img/3_2.svg";
import SVG3_2_hover from "./img/3_2_hover.svg";

import SVG3_4 from "./img/3_4.svg";
import SVG3_4_hover from "./img/3_4_hover.svg";
import SVG4_3 from "./img/4_3.svg";
import SVG4_3_hover from "./img/4_3_hover.svg";

import SVG9_16 from "./img/9_16.svg";
import SVG9_16_hover from "./img/9_16_hover.svg";
import SVG16_9 from "./img/16_9.svg";
import SVG16_9_hover from "./img/16_9_hover.svg";

import leftSVG from "./img/left.svg";

import clsx from 'clsx';
import { clamp } from 'lodash';
import designerRender from '../Designer/designerRender';

interface Iprops {
    children?: ReactNode
}

// 裁剪图片组件
const CropModel = observer((props: Iprops) => {

    const zoomList = [
        {
            icon: autoSVG,
            icon_hover: auto_hoverSVG,
            text: "自由",
            value: undefined,
        },
        {
            icon: SVG1_1,
            icon_hover: SVG1_1_hover,
            text: "1:1",
            value: 1 / 1,
        },
        {
            icon: SVG2_3,
            icon_hover: SVG2_3_hover,
            text: "2:3",
            value: 2 / 3,
        },
        {
            icon: SVG3_2,
            icon_hover: SVG3_2_hover,
            text: "3:2",
            value: 3 / 2,
        },
        {
            icon: SVG3_4,
            icon_hover: SVG3_4_hover,
            text: "3:4",
            value: 3 / 4,
        },
        {
            icon: SVG4_3,
            icon_hover: SVG4_3_hover,
            text: "4:3",
            value: 4 / 3,
        },
        {
            icon: SVG9_16,
            icon_hover: SVG9_16_hover,
            text: "9:16",
            value: 9 / 16,
        },
        {
            icon: SVG16_9,
            icon_hover: SVG16_9_hover,
            text: "16:9",
            value: 16 / 9,
        }];

    useEffect(() => {
        Taro.createSelectorQuery().select('#cropCanvas')
            .fields({ node: true, size: true, rect: true })
            .exec(res => {
                if (res[0]) {
                    const { bottom, height, left, node, nodeCanvasType, right, top, width } = res[0];
                    cropEditor.init(node);
                    cropEditor.setSize(utils.rpx2px(750), utilsStore.containerHeight - utils.rpx2px(120));
                    cropEditor.setRect({ left, top, right, bottom, width, height });

                }
            });
    }, []);

    const touchPosition = useRef<{ x: number, y: number }>({ x: 0, y: 0 });
    const hasMove = useRef<boolean>(false);
    const hasScale = useRef<boolean>(false);
    const initDistance = useRef<number>(0); // 初始的双指距离

    return (
        <div className={clsx(styles.cropModel, cropModelStore.show && styles.show)} >

            <div
                className={styles.title}
                style={{
                    height: utilsStore.titleTop,
                    paddingTop: utilsStore.safeAreaTop + utils.rpx2px(15)
                }}
            >
                <img
                    alt=""
                    src={leftSVG}
                    className={styles.leftIcon}
                    onClick={() => {
                        cropModelStore.setShow(false);
                    }}
                />

                裁剪图片
            </div>

            <div
                className={styles.cropEditor}
                style={{
                    height: utilsStore.containerHeight - utils.rpx2px(120)
                }}
                onTouchStart={(e) => {
                    e.stopPropagation();
                    e.preventDefault();
                    // console.log('ontouchstart', e.touches.length);
                    touchPosition.current.x = e.touches[0].clientX;
                    touchPosition.current.y = e.touches[0].clientY;
                    // 如果是双指触摸，则计算初始距离和角度
                    if (e.touches.length === 1) {
                        hasMove.current = false;
                        hasScale.current = false;
                        // if (e.target === e.currentTarget) {
                        //     designerRender.onTouchStart(e);
                        // }
                    } else if (e.touches.length === 2) {
                        const pointA = e.touches[0];
                        const pointB = e.touches[1];
                        const xDist = pointB.clientX - pointA.clientX;
                        const yDist = pointB.clientY - pointA.clientY;
                        initDistance.current = Math.sqrt(xDist * xDist + yDist * yDist);
                    }

                }}
                onTouchMove={(e) => {
                    e.stopPropagation();
                    e.preventDefault();
                    if (
                        !hasScale.current &&
                        cropEditor.image &&
                        (!cropEditor._currentTransform ||
                            (
                                cropEditor._currentTransform &&
                                cropEditor._currentTransform.action == "drag"
                            )
                        ) &&
                        e.touches.length === 1
                    ) {
                        const offsetX = e.touches[0].clientX - touchPosition.current.x;
                        const offsetY = e.touches[0].clientY - touchPosition.current.y;

                        // 限制裁剪框的移动范围
                        if (cropEditor.image) {
                            cropEditor.image.set({
                                left: clamp(cropEditor.image.left + offsetX,
                                    cropEditor.cropRect.left - (
                                        cropEditor.image.getScaledWidth() - cropEditor.cropRect.getScaledWidth()
                                    ),
                                    cropEditor.cropRect.left),
                                top: clamp(cropEditor.image.top + offsetY,
                                    cropEditor.cropRect.top - (
                                        cropEditor.image.getScaledHeight() - cropEditor.cropRect.getScaledHeight()
                                    ),
                                    cropEditor.cropRect.top),
                            });
                        }

                        cropEditor.requestRenderAll();
                        touchPosition.current.x = e.touches[0].clientX;
                        touchPosition.current.y = e.touches[0].clientY;
                        hasMove.current = true;

                    } else if (e.touches.length === 2) {
                        const pointA = e.touches[0];
                        const pointB = e.touches[1];
                        const xDist = pointB.clientX - pointA.clientX;
                        const yDist = pointB.clientY - pointA.clientY;
                        const currentDistance = Math.sqrt(xDist * xDist + yDist * yDist);
                        let scale = currentDistance / initDistance.current;
                        initDistance.current = currentDistance;

                        // 更具 cropReact 的宽高 限制缩放比例
                        if (cropEditor.image) {
                            scale = Math.max(cropEditor.image.scaleY * scale, cropEditor.image.scaleX * scale, cropEditor.cropRect.scaleX, cropEditor.cropRect.scaleY);

                            const offsetX = (((cropEditor.width / 2) - cropEditor.image.left) / cropEditor.image.getScaledWidth()) * cropEditor.image.width * (scale - cropEditor.image.scaleX);
                            const offsetY = (((cropEditor.height / 2) - cropEditor.image.top) / cropEditor.image.getScaledHeight()) * cropEditor.image.height * (scale - cropEditor.image.scaleY);

                            cropEditor.image.set({
                                scaleX: scale,
                                scaleY: scale,
                                left: cropEditor.image.left - offsetX,
                                top: cropEditor.image.top - offsetY,
                            });
                        }

                        // 限制裁剪框的移动范围
                        if (cropEditor.image) {
                            cropEditor.image.set({
                                left: clamp(cropEditor.image.left,
                                    cropEditor.cropRect.left - (
                                        cropEditor.image.getScaledWidth() - cropEditor.cropRect.getScaledWidth()
                                    ),
                                    cropEditor.cropRect.left),
                                top: clamp(cropEditor.image.top,
                                    cropEditor.cropRect.top - (
                                        cropEditor.image.getScaledHeight() - cropEditor.cropRect.getScaledHeight()
                                    ),
                                    cropEditor.cropRect.top),
                            });
                        }

                        hasMove.current = true;
                        hasScale.current = true;
                        cropEditor.requestRenderAll();
                    }
                }}
                onTouchEnd={(e) => {
                    e.stopPropagation();
                    e.preventDefault();
                    // console.log('ontouchend', e.touches.length);
                    if (e.touches.length === 1) {
                        // const activeObject = designerRender.getActiveObject();
                        // if (activeObject) {
                        //     designerRender._setupCurrentTransform(e, activeObject, true);
                        // }
                    } else if (
                        e.touches.length === 0 &&
                        e.target === e.currentTarget &&
                        !hasMove.current
                    ) {
                        //判断 事件对象里面的点击对象是不是自己
                        // 点击空白处取消选中状态
                        cropEditor.discardActiveObject();
                        cropEditor.mainTouchId = undefined;
                        cropEditor.requestRenderAll();
                    }

                }}
            >
                <Canvas
                    id="cropCanvas"
                    type='2d'
                    width={`${utils.rpx2px(750)}px`}
                    height={`${utilsStore.containerHeight - utils.rpx2px(120)}px`}
                    // style={{
                    //     width: '90vw',
                    //     height: '90vw',
                    // }}
                    disable-scroll={true}
                    className={styles.cropCanvas}
                    onTouchStart={(e) => {
                        // 如果是双指触摸，则计算初始距离和角度
                        if (e.touches.length === 1) {
                            cropEditor.onTouchStart(e);
                        }
                    }}
                    onTouchMove={(e) => {
                        // 如果是双指触摸，则计算双指缩放和旋转
                        if (e.touches.length === 1) {
                            cropEditor.onMouseMove(e);
                        }
                    }}
                    onTouchEnd={(e) => cropEditor.onTouchEnd(e)}
                />
            </div>

            <div className={styles.zoomList} >
                {
                    zoomList.map((item) => {
                        return (
                            <div
                                className={styles.btn}
                                onClick={() => {
                                    cropModelStore.setZoom(item.value);
                                    cropEditor.setCropZoom(item.value);
                                }}
                            >
                                <img src={cropModelStore.zoom === item.value ? item.icon_hover : item.icon} alt="" className={styles.icon} />
                                <div className={styles.text} >
                                    {item.text}
                                </div>
                            </div>
                        )
                    })
                }

            </div>

            <div className={styles.btns} >

                <div
                    className={styles.btn}
                    onClick={() => {
                        cropModelStore.setShow(false);
                    }}
                >
                    <img src={closeSVG} alt="" className={styles.icon} />
                    <div className={styles.text} >
                        取消
                    </div>
                </div>

                <div
                    className={styles.btn}
                    onClick={() => {
                        cropEditor.reset();
                        cropModelStore.setZoom(undefined);
                    }}
                >
                    <img src={backSVG} alt="" className={styles.icon} />
                    <div className={styles.text} >
                        还原
                    </div>
                </div>

                <div
                    className={styles.btn}
                    onClick={() => {
                        cropModelStore.setShow(false);
                        // 更具 cropEditor.cropRect 对象 和 cropEditor.image 的相对位置 计算出 图片的  cropX 和 cropY
                        if (cropEditor.image && cropEditor.cropRect) {
                            const cropX = (cropEditor.cropRect.left - cropEditor.image.left) / cropEditor.image.scaleX;
                            const cropY = (cropEditor.cropRect.top - cropEditor.image.top) / cropEditor.image.scaleY;
                            const cropWidth = cropEditor.cropRect.getScaledWidth() / cropEditor.image.getScaledWidth() * cropEditor.image.width;
                            const cropHeight = cropEditor.cropRect.getScaledHeight() / cropEditor.image.getScaledHeight() * cropEditor.image.height;
                            const activeObject = designerRender.getActiveObject();
                            if (activeObject && activeObject.type === 'image') {
                                const scale = Math.min(activeObject.width / cropWidth, activeObject.height / cropHeight);

                                activeObject.set({
                                    cropX,
                                    cropY,
                                    width: cropWidth,
                                    height: cropHeight,
                                    scaleX: activeObject.scaleX * scale,
                                    scaleY: activeObject.scaleY * scale,
                                });

                                // 设置遮罩居中
                                if (activeObject.clipPath) {
                                    const minScale = Math.min(activeObject.width! / activeObject.clipPath.width!, activeObject.height! / activeObject.clipPath.height!);
                                    activeObject.clipPath.left = minScale * activeObject.clipPath.width! / -2;
                                    activeObject.clipPath.top = minScale * activeObject.clipPath.height! / -2;
                                    activeObject.clipPath.scaleX = minScale;
                                    activeObject.clipPath.scaleY = minScale;
                                }

                                designerRender.requestRenderAll();
                            }
                        }

                    }}

                >
                    <img src={okSVG} alt="" className={styles.icon} />
                    <div className={styles.text} >
                        确定
                    </div>
                </div>

            </div>

        </div >
    );
});

export default CropModel;